package GUILayer;
import ModelLayer.*;
import ControlLayer.*;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.JScrollPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.ListSelectionModel;
import javax.swing.JTextField;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.util.ArrayList;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class Invoice extends JFrame {

	private int nextId;
	private JPanel contentPane;
	private JTable table;
	private JTextField txtDiscount;
	private String date;
	private JLabel lblShowdate;
	private JLabel lblShowDue;
	private JLabel lblShowId;
	private JLabel lblShowCustomer;
	private JLabel lblShowEmployee;
	private JLabel lblShowDelivery;
	private JLabel lblTotalPrice;
	private Print print;
	private SetDate setDate;
	private AddToInvoice add;
	private SalesOrder so;
	
	private IFSearch search;
	private IFCreate create;
	private IFUpdate update;
	
	private ArrayList<SalesLine> salesLines;
	
	
	/**
	 * Create the frame.
	 */
	public Invoice() {
		
		flushData();
		
		search = new SearchControler();
		create = new CreateControler();
		update = new UpdateControler();
		
		salesLines = new ArrayList<SalesLine>();
		
		setResizable(false);
		setTitle("New Invoice");
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		setBounds(150, 50, 390, 530);
		contentPane = new JPanel();
		contentPane.setBackground(new Color(255, 255, 204));
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		JLabel lblId = new JLabel("ID:");
		lblId.setBounds(10, 11, 73, 14);
		contentPane.add(lblId);
		
		nextId=create.getNextSalesOrderId();
		lblShowId = new JLabel(Integer.toString(nextId));
		lblShowId.setBounds(86, 11, 89, 14);
		contentPane.add(lblShowId);
		
		JLabel lblDate = new JLabel("Date:");
		lblDate.setBounds(10, 36, 100, 14);
		contentPane.add(lblDate);
		
		JButton btnUseToday = new JButton("Today");
		btnUseToday.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				date = DateFormat.getInstance().format(new Date());
                date = date.substring(0, 8);//ddmmyy
                lblShowdate.setText(date);
                Date newDate = new Date();
				DataHolder.getInstance().setDateHolder(newDate);
			}
		});
		btnUseToday.setBounds(86, 32, 89, 23);
		contentPane.add(btnUseToday);
		
		JButton btnSetDate = new JButton("Set Date");
		btnSetDate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setDate = new SetDate("date");
				setDate.setVisible(true);
				lblShowdate.setText(DateFormat.getInstance().format(DataHolder.getInstance().getDateHolder()).substring(0,8));
				
			}
		});
		btnSetDate.setBounds(174, 32, 89, 23);
		contentPane.add(btnSetDate);
		
		lblShowdate = new JLabel();
		lblShowdate.setBounds(301, 36, 73, 14);
		contentPane.add(lblShowdate);
		
		JLabel lblPaymentDeadline = new JLabel("Payment due:");
		lblPaymentDeadline.setBounds(10, 61, 100, 14);
		contentPane.add(lblPaymentDeadline);
		
		JButton btnSetDueDay = new JButton("Set Date");
		btnSetDueDay.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				setDate = new SetDate("");
				setDate.setVisible(true);
			}
		});
		btnSetDueDay.setBounds(86, 57, 89, 23);
		contentPane.add(btnSetDueDay);
		
		lblShowDue = new JLabel("");
		lblShowDue.setBounds(301, 61, 73, 14);
		contentPane.add(lblShowDue);
		
		JLabel lblCustomer = new JLabel("Customer:");
		lblCustomer.setBounds(10, 86, 100, 14);
		contentPane.add(lblCustomer);
		
		JButton btnAddCustomer = new JButton("Add");
		btnAddCustomer.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				add = new AddToInvoice("customer");
				add.setVisible(true);
				add.addWindowFocusListener(new WindowFocusListener() {
					@Override
					public void windowGainedFocus(WindowEvent arg0) {
						add.refreshTCustomer();
						}
					@Override
					public void windowLostFocus(WindowEvent arg0) {
					}
				});
				add.setVisible(true);
			}
		});

		btnAddCustomer.setBounds(86, 82, 89, 23);
		contentPane.add(btnAddCustomer);
		
		lblShowCustomer = new JLabel("");
		lblShowCustomer.setBounds(301, 86, 73, 14);
		contentPane.add(lblShowCustomer);
		
		JLabel lblEmployee = new JLabel("Employee:");
		lblEmployee.setBounds(10, 111, 100, 14);
		contentPane.add(lblEmployee);
		
		JButton btnAddEmployee = new JButton("Add");
		btnAddEmployee.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				add = new AddToInvoice("employee");
				add.addWindowFocusListener(new WindowFocusListener() {
					@Override
					public void windowGainedFocus(WindowEvent arg0) {
						add.refreshTEmployee();
					}
					@Override
					public void windowLostFocus(WindowEvent arg0) {
					}
				});
				add.setVisible(true);
			}
		});
		btnAddEmployee.setBounds(86, 107, 89, 23);
		contentPane.add(btnAddEmployee);

		lblShowEmployee = new JLabel("");
		lblShowEmployee.setBounds(301, 111, 73, 14);
		contentPane.add(lblShowEmployee);
				
		JLabel lblProducts = new JLabel("Products:");
		lblProducts.setBounds(10, 136, 100, 14);
		contentPane.add(lblProducts);
		
		JButton btnAddProduct = new JButton("Add");
		btnAddProduct.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				add = new AddToInvoice("product");
				add.setVisible(true);
				add.addWindowFocusListener(new WindowFocusListener() {
					@Override
					public void windowGainedFocus(WindowEvent arg0) {
						add.refreshTProduct();
						}
					@Override
					public void windowLostFocus(WindowEvent arg0) {
					}
				});
				add.setVisible(true);
			}
		});
		btnAddProduct.setBounds(86, 132, 89, 23);
		contentPane.add(btnAddProduct);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(10, 161, 364, 200);
		contentPane.add(scrollPane);
		
		salesLines = DataHolder.getInstance().getSalesLineHolder();
		table = new JTable();
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.setFillsViewportHeight(true);
		setTableOfProducts(table, salesLines);
		table.getColumnModel().getColumn(0).setResizable(false);
		table.getColumnModel().getColumn(1).setResizable(false);
		table.getColumnModel().getColumn(2).setResizable(false);
		table.getColumnModel().getColumn(3).setResizable(false);
		table.getColumnModel().getColumn(4).setResizable(false);
		scrollPane.setViewportView(table);
		
		JLabel lblDiscount = new JLabel("Discount:");
		lblDiscount.setBounds(10, 369, 100, 14);
		contentPane.add(lblDiscount);
		
		txtDiscount = new JTextField("0");
		txtDiscount.setBounds(174, 366, 89, 20);
		contentPane.add(txtDiscount);
		txtDiscount.setColumns(10);
		
		JLabel lblTotal = new JLabel("Total:");
		lblTotal.setBounds(10, 440, 46, 14);
		contentPane.add(lblTotal);
		
		JLabel lblDelivery = new JLabel("Delivery:");
		lblDelivery.setBounds(10, 394, 46, 14);
		contentPane.add(lblDelivery);
		
		JButton btnAddDelivery = new JButton("Add");
		btnAddDelivery.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				add = new AddToInvoice("delivery");
				add.setVisible(true);
				add.addWindowFocusListener(new WindowFocusListener() {
					@Override
					public void windowGainedFocus(WindowEvent arg0) {
						add.refreshTDelivery();
					}
					@Override
					public void windowLostFocus(WindowEvent arg0) {
					}
				});
				add.setVisible(true);
			}
		});
		btnAddDelivery.setBounds(174, 390, 89, 23);
		contentPane.add(btnAddDelivery);
		
		lblShowDelivery = new JLabel("");
		lblShowDelivery.setBounds(301, 394, 73, 14);
		contentPane.add(lblShowDelivery);
		
		lblTotalPrice = new JLabel("");
		lblTotalPrice.setText(Double.toString(create.calculateTotal(salesLines)));
		lblTotalPrice.setBounds(174, 440, 89, 14);
		contentPane.add(lblTotalPrice);
		
		JButton btnSave = new JButton("Save");
		btnSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String discount = txtDiscount.getText();
				int d;
				boolean error = false;
				if(!discount.equals(""))
				{
					try
					{
						Integer.parseInt(discount);
					}
					catch(Exception f)
					{
						JOptionPane.showMessageDialog(null,
			                    "The discount has to be a number!",
			                    "Warning",
			                    JOptionPane.WARNING_MESSAGE);
						error = true;
					}
				}
				if(!error)
				{
					if(discount.equals(""))
					{
						d=0;
					}
					else
					{
						d = Integer.parseInt(discount);
					}
					saveInvoice(nextId, d);
				}
			}
		});
		btnSave.setBounds(10, 465, 89, 23);
		contentPane.add(btnSave);
		
		JButton btnCancel = new JButton("Cancel");
		btnCancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				dispose();
			}
		});
		btnCancel.setBounds(285, 465, 89, 23);
		contentPane.add(btnCancel);
		
		
		
	}

	public void flushData()
	{
		DataHolder.getInstance().flushData();
	}
	
	private void setTableOfProducts(JTable jTable, ArrayList<SalesLine> salesLines) {
		if(salesLines == null)
		{
			DefaultTableModel model = new DefaultTableModel();
		    jTable.setModel(model);
		    model.setColumnIdentifiers(new String[]{"ID", "Name", "Price", "Quantity", "Subtotal"});
		}
		else{
			DefaultTableModel model = new DefaultTableModel();
		    jTable.setModel(model);
		    model.setColumnIdentifiers(new String[]{"ID", "Name", "Price", "Quantity", "Subtotal"});
		    for (SalesLine s : salesLines) {
		        double subtotal = (s.getP().getNettPrice() + s.getP().getNettPrice() * s.getP().getTax() / 100 ) * s.getQuantity();
		    	model.addRow(new String[]{Integer.toString(s.getP().getId()), s.getP().getName(), Double.toString(s.getP().getNettPrice()),Integer.toString(s.getQuantity()), Double.toString(subtotal)});
		    }
		}
	}
	
	private void refreshDateLbl()
	{
		if(DataHolder.getInstance().getDateHolder()!=null)
		{
			if(DataHolder.getInstance().getDueHolder()!=null)
			{
				lblShowdate.setText(DateFormat.getInstance().format(DataHolder.getInstance().getDateHolder()).substring(0,8));
				lblShowDue.setText(DateFormat.getInstance().format(DataHolder.getInstance().getDueHolder()).substring(0,8));
			}
			else
			{
				lblShowdate.setText(DateFormat.getInstance().format(DataHolder.getInstance().getDateHolder()).substring(0,8));
			}
		}
		else
		{
			if(DataHolder.getInstance().getDueHolder()!=null)
			{
				lblShowDue.setText(DateFormat.getInstance().format(DataHolder.getInstance().getDueHolder()).substring(0,8));
			}
		}
		System.out.println("refreshed date labels");
	}
	
	private void refreshCustomerLbl()
	{
		if(DataHolder.getInstance().getCustomerHolder()!=null)
		{
			lblShowCustomer.setText(Integer.toString(DataHolder.getInstance().getCustomerHolder().getId()));
		}
		System.out.println("refreshed customer lbl");
	}
	
	private void refreshEmployeelbl()
	{
		if(DataHolder.getInstance().getEmployeeHolder()!=null)
		{
			lblShowEmployee.setText(Integer.toString(DataHolder.getInstance().getEmployeeHolder().getId()));
		}
		System.out.println("refreshed employee lbl");
	}
	
	private void refreshDeliveryLbl()
	{
		if(DataHolder.getInstance().getDeliveryHolder()!=null)
		{
			lblShowDelivery.setText(Integer.toString(DataHolder.getInstance().getDeliveryHolder().getDeliveryId()));
		}
		System.out.println("refreshed delivery lbl");
	}
	
	private void refreshTable()
	{
		salesLines = DataHolder.getInstance().getSalesLineHolder();
		if(salesLines.size() != 0)
		{
			setTableOfProducts(table, salesLines);
		}
		System.out.println("refreshed table");
	}
	
	private void refreshTotal()
	{
		if(salesLines.size()!=0)
		{
			lblTotalPrice.setText(Double.toString(create.calculateTotal(salesLines)));
		}
		System.out.println("refreshed total");
	}

	private void saveInvoice(int id, int discount)
	{
		if(DataHolder.getInstance().getDateHolder()==null || DataHolder.getInstance().getDueHolder()==null || DataHolder.getInstance().getCustomerHolder()==null || DataHolder.getInstance().getEmployeeHolder()==null || DataHolder.getInstance().getSalesLineHolder().size() == 0 || DataHolder.getInstance().getDeliveryHolder()==null)
		{
			JOptionPane.showMessageDialog(null,
                    "All data has to be inserted.",
                    "Warning",
                    JOptionPane.WARNING_MESSAGE);
		}
		else
		{
			SalesOrder salesOrder = new SalesOrder(id, DataHolder.getInstance().getDateHolder(), DataHolder.getInstance().getDueHolder(), create.calculateTotal(salesLines), "Created", discount, DataHolder.getInstance().getCustomerHolder(), DataHolder.getInstance().getEmployeeHolder(), DataHolder.getInstance().getSalesLineHolder(), DataHolder.getInstance().getDeliveryHolder());
			try {
				create.createOrder(salesOrder);
			} catch (Exception e) {
				JOptionPane.showMessageDialog(null,
                        "Something went wrong, please try again!",
                        "Warning",
                        JOptionPane.WARNING_MESSAGE);
				e.printStackTrace();
			}
			MainWindow.getInstance().refreshTableInvoice();
			dispose();
		}
	}
	
	public void refreshLbls()
	{
		refreshDateLbl();
		refreshCustomerLbl();
		refreshEmployeelbl();
		refreshTable();
		refreshDeliveryLbl();
		refreshTotal();
	}
		
}
